package com.example.leonard.aop;

import com.example.leonard.annotation.RateLimit;
import com.example.leonard.common.utils.IPUtils;
import com.example.leonard.service.RateLimitService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @auther heyan g
 * @date 2021/8/29 16:19
 */
@Aspect
@Component
public class RateLimitAspect {
    @Autowired
    private RateLimitService rateLimitService;

    @Around(value = "@annotation(rateLimit)")
    public Object rateLimit(ProceedingJoinPoint joinPoint, RateLimit rateLimit) {
        try {
            //todo 居群环境需要添加分布式锁
            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            String ipAddr = IPUtils.getIpAddr(request);
            System.out.println("本机ip" + ipAddr);

            String value = rateLimit.value();
            System.out.println("注解上的参数" + value);

            Signature signature = joinPoint.getSignature();
            String name = signature.getName();
            System.out.println("方法名称" + name);
            System.out.println("signature" + signature);
            Object[] args = joinPoint.getArgs();
            System.out.println("方法上的参数" + args[0]);
            rateLimitService.rateLimit(ipAddr, value);
            Object result = joinPoint.proceed();
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw new RuntimeException("aop异常");
        }
    }
}
